import json
import time
import logging
import datetime
import pandas as pd

import QUANTAXIS as QA
from QUANTAXIS.QAARP import QA_Risk
from QIFIAccount.QIFIAccount.QARealtimeStockSim import QIFI_StockSIM_Account
from QAStrategy.QAStrategy.classic_strategy.turtle_strategy import TurtleTrade


def gen_params():
    pos_2 = [[1.0, 0.8, 0.5, 0.2, 0.0],
             [0.9, 0.7, 0.5, 0.3, 0.1],
             [0.8, 0.7, 0.5, 0.3, 0.2],
             # [0.7, 0.6, 0.5, 0.4, 0.3]
             ]
    pos_3 = [[1.0, 0.9, 0.7, 0.5, 0.3, 0.1, 0.0],
             [0.9, 0.8, 0.7, 0.5, 0.3, 0.2, 0.1],
             # [0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2]
             ]
    dis_2 = [
             [-3, -2, 2, 3],
             [-2, -1, 1, 2]]
    dis_3 = [[-3, -2, -1, 1, 2, 3]]
    errs = ['std', 'atr']
    freq = [QA.FREQUENCE.FIVE_MIN, QA.FREQUENCE.FIFTEEN_MIN, QA.FREQUENCE.THIRTY_MIN, QA.FREQUENCE.SIXTY_MIN]
    for f in freq:
        for n in [30, 60, 90, 150, 180, 300]:
            for dead in [0, 0.1, 0.3, 0.5]:
                for i in range(2, 4):
                    if i is 2:
                        for pos in pos_2:
                            for dis in dis_2:
                                for err in errs:
                                    if err == 'atr':
                                        for ratio in [1, 2, 3]:
                                            yield f, n, dead, pos, dis, err, ratio
                                    else:
                                        yield f, n, dead, pos, dis, err, 1
                    else:
                        for pos in pos_3:
                            for dis in dis_3:
                                for err in errs:
                                    if err == 'atr':
                                        for ratio in [1, 2, 3]:
                                            yield f, n, dead, pos, dis, err, ratio
                                    else:
                                        yield f, n, dead, pos, dis, err, 1


def main_muti():
    # account
    username = 'admin'
    password = 'admin'

    # strategy
    print('start execute strategy')
    today = datetime.date.today()
    last_year = datetime.date.today() + datetime.timedelta(days=-365)

    start = last_year.strftime('%Y-%m-%d')
    end = today.strftime('%Y-%m-%d')
    start = '2020-07-04'
    end = '2020-10-13'

    t = datetime.datetime.now()
    index = 0
    df = pd.DataFrame()
    for f, n, dead, pos, dis, err, r in gen_params():
        strategy = TurtleTrade(username='turtle_backtest_stock_index_min', password='123456', code='601633',
                               market=QA.MARKET_TYPE.STOCK_CN, start=start, end=end, show_trade=False,
                               frequence=f, strategy_id=username, init_cash=1e5,
                               min_trade_money=5000, ratio=0.8,
                               n_up=55, n_down=20, n_short_ma=10, n_long_ma=60, n_atr=20)
        strategy.run_backtest()
        # strategy.plot_grid()
        if strategy.trade_start_time is None:  # 防止评估没有交易记录的账户
            continue
        risk = QA_Risk(strategy.acc)
        # print(risk.risk_message)
        s = pd.Series(risk.risk_message)
        s['start'] = strategy.trade_start_time
        s['end'] = end
        s['err'] = err
        s['atr_r'] = r
        s['freq'] = f
        s['N'] = n
        s['deadband'] = dead
        s['pos'] = pos
        s['dis'] = dis
        df = df.append(s.to_frame().T)
        # print(df)
        # risk.plot_assets_curve().show()
        df.to_csv('bt_result_min.csv')
        index += 1
        print(index, f, n, dead, pos, dis, err, r, 'return:', s['annualize_return'], 'time:', datetime.datetime.now() - t)


def main():
    # account
    username = 'admin'
    password = 'admin'

    # strategy
    print('start execute strategy')
    today = datetime.date.today()
    last_week = datetime.date.today() + datetime.timedelta(days=-30)
    last_year = datetime.date.today() + datetime.timedelta(days=-365)

    start = last_week.strftime('%Y-%m-%d')
    end = today.strftime('%Y-%m-%d')
    end = QA.QA_util_get_pre_trade_date(end, n=1)
    start = '2020-06-20'
    end = '2020-10-13'

    strategy = TurtleTrade(username='turtle_backtest_min', password='123456', code='510300',
                         market=QA.MARKET_TYPE.INDEX_CN, start=start, end=end, show_trade=True,
                         min_trade_money=3000,
                         frequence=QA.FREQUENCE.SIXTY_MIN, strategy_id=username, init_cash=1e5,
                         ratio=0.8, n_up=55, n_down=20, n_short_ma=10, n_long_ma=60, n_atr=20)
    strategy.run_backtest()
    # strategy.plot_grid()
    risk = QA_Risk(strategy.acc)
    # print(risk.risk_message)
    # s = pd.Series(risk.risk_message)
    # s['start'] = start
    # print(s)
    df = pd.DataFrame.from_dict(risk.risk_message, orient='index', columns=['values']).T
    # df.to_csv('bt_result.csv')
    risk.plot_assets_curve()
    # risk.plot_dailyhold()
    # risk.plot_signal()

if __name__ == "__main__":
    try:
        from QUANTAXIS_RealtimeCollector.QARealtimeCollector.utils.logconf import update_log_file_config
        logfile = 'stock.backtest.log'
        logging.config.dictConfig(update_log_file_config(logfile))
    except Exception as e:
        print(e.__str__())
    # main_muti()
    main()